
import com.google.java.contract.*;

@Invariant({"getWidth() > 0", "getHeight() > 0", "getDepth() > 0"})
public class Cart {
	
	private float x;
	private float y;
	private float z;
	
	private float width; //x length
	private float height; //y length
	private float depth; //z length
	
	private float speed;
	
	private float distanceTravelled;
	
	private Rollercoaster theCoaster;
	
	@Requires({"sWidth > 0", "sHeight > 0", "sDepth > 0"})
	public Cart(float sX, float sY, float sZ, float sWidth, float sHeight, float sDepth, float sSpeed, Rollercoaster track) {
		distanceTravelled = 0;
		
		x = sX;
		y = sY;
		z = sZ;
		
		width = sWidth;
		height = sHeight;
		depth = sDepth;
		
		speed = sSpeed;
		
		theCoaster = track;
	}
	
	public Cart(Point3D position, Point3D dimension, float sSpeed, Rollercoaster track) {
		distanceTravelled = 0;
		
		x = position.x;
		y = position.y;
		z = position.z;
		
		width = dimension.x;
		height = dimension.y;
		depth = dimension.z;
		
		speed = sSpeed;
		
		theCoaster = track;
	}
	
	public Cart(Point3D dimension, float sSpeed, Rollercoaster track) {
		distanceTravelled = 0;
		
		x = track.getStartX();
		y = track.getStartY();
		z = track.getStartZ();
		
		width = dimension.x;
		height = dimension.y;
		depth = dimension.z;
		
		speed = sSpeed;
		
		theCoaster = track;
	}
	
	//needs fps calculation, perhaps held in static game manager, within game manager itself?
	//this will also handle speed manipulations, currently speed will be constant?
	//may need some sort of autocorrection to account for rounding errors?
	public void move() {
		
	}
	
	public float getX() {
		return x;
	}
	
	public float getY() {
		return y;
	}
	
	public float getZ() {
		return z;
	}
	
	@Ensures("getX() == newX")
	public void setX(float newX) {
		x = newX;
	}
	
	@Ensures("getY() == newY")
	public void setY(float newY) {
		y = newY;
	}
	
	@Ensures("getZ() == newZ")
	public void setZ(float newZ) {
		z = newZ;
	}
	
	public float getWidth() {
		return width;
	}
	
	public float getHeight() {
		return height;
	}
	
	public float getDepth() {
		return depth;
	}
	
	@Requires("newWidth > 0")
	@Ensures("getWidth() == newWidth")
	public void setWidth(float newWidth) {
		width = newWidth;
	}
	
	@Requires("newHeight > 0")
	@Ensures("getHeight() == newHeight")
	public void setHeight(float newHeight) {
		height = newHeight;
	}
	
	@Requires("newDepth > 0")
	@Ensures("getDepth() == newDepth")
	public void setDepth(float newDepth) {
		depth = newDepth;
	}
	
	public float getSpeed() {
		return speed;
	}
	
	@Ensures("getSpeed() == newSpeed")
	public void setSpeed(float newSpeed) {
		speed = newSpeed;
	}
	
	public float getDistanceTravelled() {
		return distanceTravelled;
	}
	
	public void resetDistanceTravelled() {
		distanceTravelled = 0;
	}

}
